package com.iscale.system.log;

import com.iscale.model.entity.SysLog;
import com.iscale.service.SystemLogService;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: ouyangan
 * @Date : 2016/10/15
 */
@Aspect
@Component
@Order(2)
public class LogAOP {
    private static final Logger logger = LoggerFactory.getLogger(LogAOP.class);

    @Autowired
    private SystemLogService systemLogService;

    @Around("@within(org.springframework.web.bind.annotation.RequestMapping)")
    public Object recordLog(ProceedingJoinPoint p) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        Object o = null;
        long t1 = System.currentTimeMillis();
        try {
            o = p.proceed();
        } catch (Exception e) {//这里建议将异常向上层抛让异常处理器来进行捕捉
            if (e instanceof UnknownAccountException) {
                throw new UnknownAccountException(e);
            } else if (e instanceof IncorrectCredentialsException) {
                throw new IncorrectCredentialsException(e);
            } else if (e instanceof UnauthorizedException) {
                throw new UnauthorizedException(e);
            } else if (e instanceof UnauthenticatedException) {
                throw new UnauthenticatedException(e);
            } else {
                throw new Exception(e);
            }
        }
        SysLog log = new SysLog();
        long t2 = System.currentTimeMillis();
        if (o != null && o.toString().length() < 5000) {
            log.setRepResult(o.toString());
        } else {
            log.setRepResult("data is too long");
        }
        log.setDuration((t2 - t1));
        log.setReqMethod(p.getTarget().getClass().getName() + "." + p.getSignature().getName());
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : request.getParameterMap().keySet()) {
            if (!s.contains("password")) {
                stringBuilder.append(s);
                stringBuilder.append(" = ");
                stringBuilder.append(request.getParameterMap().get(s)[0]);
                stringBuilder.append(" | ");
            }
        }
        log.setReqParam(stringBuilder.toString());
        log.setReqIp(request.getRemoteAddr());
        log.setReqUrl(request.getRequestURL().toString());
        log.setReqAgent(request.getHeader("user-agent"));
        systemLogService.insertSysControllerLog(log);

        logger.info("request contentType:{}", request.getHeader("Accept"));
        logger.info("request param : {}", log.getReqParam());
        logger.info("reuest method : {}", request.getMethod());
        logger.info("request url : {}", log.getReqUrl());
        return o;
    }

}
